﻿using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Wuther.Infrastructure.Menus;
using Wuther.Infrastructure.Organizations;
using static Volo.Abp.Identity.Settings.IdentitySettingNames;

namespace Wuther.Infrastructure.Users
{
    /// <summary>
    /// 用户管理扩展
    /// </summary>
    [RemoteService(IsEnabled = false)]
    public class UsersAppService : IdentityUserAppService, IUsersAppService
    {
        private readonly IRepository<IdentityUser, Guid> _repository;
        private readonly IdentityUserManager _userManager;
        private readonly IOrganizationUsersAppService _organizationUsersAppService;
        protected IPermissionChecker PermissionChecker { get; }
        public UsersAppService(IdentityUserManager userManager,
            IIdentityUserRepository userRepository,
            IIdentityRoleRepository roleRepository,
            IOptions<IdentityOptions> identityOptions,
            IRepository<IdentityUser, Guid> repository,
            IPermissionChecker permissionChecker,
            IOrganizationUsersAppService organizationUsersAppService
            ) : base(userManager, userRepository, roleRepository, identityOptions, permissionChecker)
        {
            _userManager = userManager;
            _repository = repository;
            _organizationUsersAppService = organizationUsersAppService;
        }
        #region 获取所有用户
        /// <summary>
        /// 获取所有用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UserOptionsDto>> GetAllUsers(GetAllUsersInput input)
        {
            var userIds = new List<Guid>();
            //if (input.OrganizationId.HasValue)
            //{
            //    userIds = (await _organizationUsersAppService.GetAllListAsync(new GetOrganizationUsersInput { OrganizationId = input.OrganizationId })).Select(s => s.UserId).ToList();
            //}
            var list = await (await _repository.GetQueryableAsync()).WhereIf(!string.IsNullOrWhiteSpace(input.Name), w => EF.Functions.Like(w.Name, $"%{input.Name}%")).WhereIf(!string.IsNullOrWhiteSpace(input.UserName), w => EF.Functions.Like(w.UserName, $"%{input.UserName}%")).WhereIf(userIds != null && userIds.Count > 0, w => userIds.Contains(w.Id)).ToListAsync();

            return ObjectMapper.Map<List<IdentityUser>, List<UserOptionsDto>>(list);


        }
        #endregion

        #region 获取用户详细信息
        /// <summary>
        /// 获取用户详细信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<IdentityUserDto>> GetAllUsersInfoAsync(GetAllUsersInput input)
        {
            var userIds = new List<Guid>();
            //if (input.OrganizationId.HasValue)
            //{
            //    userIds = (await _organizationUsersAppService.GetAllListAsync(new GetOrganizationUsersInput { OrganizationId = input.OrganizationId })).Select(s => s.UserId).ToList();
            //}
            var list = await (await _repository.GetQueryableAsync()).WhereIf(!string.IsNullOrWhiteSpace(input.Name), w => EF.Functions.Like(w.Name, $"%{input.Name}%")).WhereIf(!string.IsNullOrWhiteSpace(input.UserName), w => EF.Functions.Like(w.UserName, $"%{input.UserName}%")).WhereIf(userIds != null && userIds.Count > 0, w => userIds.Contains(w.Id)).ToListAsync();
            return ObjectMapper.Map<List<IdentityUser>, List<IdentityUserDto>>(list);

        }
        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <returns></returns>
        public async Task<CurrentUserInfo> GetCurrentUserAsync()
        {
            var info = new CurrentUserInfo
            {
                UserName = CurrentUser.UserName,
                Name = CurrentUser.UserName,
                Roles = CurrentUser.Roles,
                Avatar = await GetUserAvatarAsync(null)
            };

            var orgs = await _organizationUsersAppService.GetAllListAsync(new GetOrganizationUsersInput { UserId = CurrentUser.Id });
            if (orgs.Count > 0)
            {
                info.OrganizationIds = orgs.Select(s => s.OrganizationId).ToList();
                info.OrganizationNames = orgs.Select(s => s.OrganizationName).ToList();
            }
            return info;
        }
        #endregion

        #region 获取用户详情
        /// <summary>
        /// 获取用户详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<UserInfoDto> GetUserInfoById(Guid Id)
        {
            var user = await UserManager.GetByIdAsync(Id);
            var userClaims = await _userManager.GetClaimsAsync(user);

            var res = ObjectMapper.Map<IdentityUser, UserInfoDto>(user);
            res.Avatar = userClaims.FirstOrDefault(c => c.Type == "avatar")?.Value;
            res.WebSite = userClaims.FirstOrDefault(c => c.Type == "website")?.Value;

            return res;
        }
        #endregion
        /// <summary>
        /// 获取用户头像
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<string> GetUserAvatarAsync(Guid? id)
        {
            if (id == null)
            {
                if (CurrentUser.Id == null)
                {
                    throw new UserFriendlyException("未找到该用户");
                }
                id = CurrentUser.Id;
            }
            var user = await _userManager.GetByIdAsync(id.Value);
            var userClaims = await _userManager.GetClaimsAsync(user);

            return userClaims.FirstOrDefault(c => c.Type == "avatar")?.Value;

        }
        /// <summary>
        /// 设置用户头像
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task SetUserAvatarAsync(Guid? id, string url)
        {
            if (id == null)
            {
                if (CurrentUser.Id == null)
                {
                    throw new UserFriendlyException("未找到该用户");
                }
                id = CurrentUser.Id;
            }
            var user = await _userManager.GetByIdAsync(id.Value);
            var userClaims = await _userManager.GetClaimsAsync(user);
            var avatar = userClaims.FirstOrDefault(c => c.Type == "avatar");
            if (avatar != null)
            {
                await _userManager.RemoveClaimAsync(user, avatar);
            }
            await _userManager.AddClaimAsync(user, new System.Security.Claims.Claim("avatar", url));
        }

        /// <summary>
        /// 根据用户ids获取用户
        /// </summary>
        /// <param name="userIds"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<UserInfoDto>> GetUsersByIdsAsync(List<Guid> userIds)
        {
            var list = await (await _repository.GetQueryableAsync()).WhereIf(userIds != null && userIds.Any(), w => userIds.Contains(w.Id)).ToListAsync();
            var res = new List<UserInfoDto>();
            foreach (var user in list)
            {
                var entity = ObjectMapper.Map<IdentityUser, UserInfoDto>(user);
                var userClaims = await _userManager.GetClaimsAsync(user);
                entity.Avatar = userClaims.FirstOrDefault(c => c.Type == "avatar")?.Value;
                entity.WebSite = userClaims.FirstOrDefault(c => c.Type == "website")?.Value;

                res.Add(entity);
            }
            return res;
        }

        public async Task<List<MenuDto>> GetUserMenus()
        {
            List<MenuDto> menuList = new List<MenuDto>
            {
                new MenuDto
                {
                    Id = 1,
                    ParentId = null,
                    Name = "System Management",
                    Path = "/system",
                    Permission = "system:manage",
                    Type = 0,
                    Icon = "system",
                    OrderNo = 1,
                    Component = "Layout",
                    IsExt = false,
                    ExtOpenMode = 1,
                    KeepAlive = 1,
                    Show = 1,
                    ActiveMenu = "",
                    Status = 1,
                },
                new MenuDto
                {
                    Id = 2,
                    ParentId = 1,
                    Name = "User Management",
                    Path = "/system/user",
                    Permission = "system:user:manage",
                    Type = 1,
                    Icon = "user",
                    OrderNo = 2,
                    Component = "system/user/index",
                    IsExt = false,
                    ExtOpenMode = 1,
                    KeepAlive = 1,
                    Show = 1,
                    ActiveMenu = "/system",
                    Status = 1,
                }
            };


            return menuList;
        }


    }
}
